package com.example.publice.quartz;


import com.alibaba.druid.pool.DruidDataSource;
import org.quartz.Scheduler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;

import javax.sql.DataSource;
import java.util.Properties;

/**
 *
 */
@Configuration
public class QuartzConfig {

    @Autowired
    private JobFactory jobFactory;

    @Value("${org.quartz.jobStore.useProperties}")
    private String useProperties;
    @Value("${org.quartz.scheduler.instanceName}")
    private String instanceName;
    @Value("${org.quartz.scheduler.instanceId}")
    private String instanceId;


    @Value("${org.quartz.threadPool.class}")
    private String threadPool;
    @Value("${org.quartz.threadPool.threadCount}")
    private String threadCount;
    @Value("${org.quartz.threadPool.threadPriority}")
    private String threadPriority;
    @Value("${org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread}")
    private String threadsInheritContextClassLoaderOfInitializingThread;


    @Value("${org.quartz.jobStore.class}")
    private String jobStore;
    @Value("${org.quartz.jobStore.driverDelegateClass}")
    private String driverDelegateClass;

    @Value("${org.quartz.jobStore.isClustered}")
    private String isClustered;
    @Value("${org.quartz.jobStore.clusterCheckinInterval}")
    private String clusterCheckinInterval;
    @Value("${org.quartz.jobStore.tablePrefix}")
    private String tablePrefix;


    private Properties quartzProperties() {
        Properties prop = new Properties();
        prop.put("org.quartz.jobStore.useProperties", useProperties);
        // 调度标识名 集群中每一个实例都必须使用相同的名称
        prop.put("org.quartz.scheduler.instanceName", instanceName);
        // ID设置为自动获取 每一个必须不同
        prop.put("org.quartz.scheduler.instanceId", instanceId);
        // 禁用quartz软件更新
        prop.put("org.quartz.scheduler.skipUpdateCheck", "true");
        prop.put("org.quartz.scheduler.jmx.export", "true");

        // 数据库代理类，一般org.quartz.impl.jdbcjobstore.StdJDBCDelegate可以满足大部分数据库
        prop.put("org.quartz.jobStore.driverDelegateClass", driverDelegateClass);
        // 数据保存方式为数据库持久化
        prop.put("org.quartz.jobStore.class", jobStore);
        // 表的前缀，默认QRTZ_
        prop.put("org.quartz.jobStore.tablePrefix", tablePrefix);
        // 是否加入集群
        prop.put("org.quartz.jobStore.isClustered", isClustered);

        // 调度实例失效的检查时间间隔
        prop.put("org.quartz.jobStore.clusterCheckinInterval", "20000");
        prop.put("org.quartz.jobStore.maxMisfiresToHandleAtATime", "1");
        // 信息保存时间 ms 默认值60秒
        prop.put("org.quartz.jobStore.misfireThreshold", "120000");
        prop.put("org.quartz.jobStore.txIsolationLevelSerializable", "true");
        prop.put("org.quartz.jobStore.selectWithLockSQL", "SELECT * FROM {0}LOCKS WHERE LOCK_NAME = ? FOR UPDATE");

        // 程池的实现类（一般使用SimpleThreadPool即可满足几乎所有用户的需求）
        prop.put("org.quartz.threadPool.class", threadPool);
        // 定线程数，至少为1（无默认值）(一般设置为1-100之间的整数合适)
        prop.put("org.quartz.threadPool.threadCount", threadCount);
        // 设置线程的优先级（最大为java.lang.Thread.MAX_PRIORITY 10，最小为Thread.MIN_PRIORITY 1，默认为5）
        prop.put("org.quartz.threadPool.threadPriority", threadPriority);
        prop.put("org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread", threadsInheritContextClassLoaderOfInitializingThread);

        prop.put("org.quartz.plugin.triggHistory.class", "org.quartz.plugins.history.LoggingJobHistoryPlugin");
        prop.put("org.quartz.plugin.shutdownhook.class", "org.quartz.plugins.management.ShutdownHookPlugin");
        prop.put("org.quartz.plugin.shutdownhook.cleanShutdown", "true");

        //#自定义连接池
        //org.quartz.dataSource.myDS.connectionProvider.class=com.poly.pay.schedule.DruidConnectionProvider

        return prop;
    }


    @ConfigurationProperties(prefix = "spring.datasource")
    @Bean(name = "quartzDruidDataSource")
    public DataSource druidDataSource() {
        return new DruidDataSource();
    }

    @Bean
    public SchedulerFactoryBean schedulerFactoryBean() {
        SchedulerFactoryBean schedulerFactoryBean = new SchedulerFactoryBean();
        schedulerFactoryBean.setJobFactory(jobFactory);
        // 用于quartz集群,QuartzScheduler 启动时更新己存在的Job
        schedulerFactoryBean.setOverwriteExistingJobs(true);
        //延长启动
        schedulerFactoryBean.setStartupDelay(1);
        //设置加载的配置文件
//        schedulerFactoryBean.setConfigLocation(new ClassPathResource("/quartz.properties"));
        schedulerFactoryBean.setQuartzProperties(quartzProperties());
        schedulerFactoryBean.setDataSource(druidDataSource());
        return schedulerFactoryBean;
    }

    @Bean
    public Scheduler scheduler() {
        return schedulerFactoryBean().getScheduler();
    }


}
